package com.cocos.game;

import android.util.Log;
import android.widget.Toast;

import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClient.BillingResponseCode;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.ProductDetails;
import com.android.billingclient.api.ProductDetailsResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.QueryProductDetailsParams;
import com.android.billingclient.api.QueryPurchasesParams;

import com.google.common.collect.ImmutableList;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class GooglePay implements PurchasesUpdatedListener {
    public String TAG = "xxxjpay";
    public static GooglePay instance;
    public AppActivity context;
    public static void init() {
        instance = new GooglePay();
        instance.context = AppActivity.act;
        instance.initSDK();
    }
    private BillingClient billingClient;
    public void initSDK() {
        Log.d(TAG, "initSDK: ");
        billingClient = BillingClient.newBuilder(context)
                .setListener(this)
                // Configure other settings.
                .enablePendingPurchases()
                .build();
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
                    // The BillingClient is ready. You can query purchases here.
                }
            }
            @Override
            public void onBillingServiceDisconnected() {
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
            }
        });
    }
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
        int responseCode = billingResult.getResponseCode();
        Log.d(TAG, "onPurchasesUpdated: " + responseCode);
        if (responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
            // xj 购买完成
            for (Purchase purchase : purchases) {
                Log.e(TAG, "getPurchaseToken: "+ purchase.getPurchaseToken() );
                Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                Log.e(TAG, "getSignature: "+ purchase.getSignature() );
//                handlePurchase(purchase);
                onPaySuccess(purchase);
            }
        } else {
            onPayFail(responseCode);
        }
    }

    private void onPaySuccess(Purchase purchase){
        String token = purchase.getPurchaseToken();
        String transactionId = purchase.getOrderId();
//        List<String> skus = purchase.getProducts();
        JSONObject jo = new JSONObject();
        try {
            jo.put("token", token);
            jo.put("transactionId", transactionId);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
        JsbHelper.emit("respPaySuccess",jo.toString());
    }

    private void onPayFail(int msgCode){
        Log.d(TAG, "onPayFail: " + msgCode);
        JsbHelper.emit("respPayFail",msgCode + "");
    }

    public void getProducts(String productId) {
        List<QueryProductDetailsParams.Product> productList= new ArrayList<>();
        productList.add(QueryProductDetailsParams.Product.newBuilder()
                .setProductId(productId).setProductType(BillingClient.ProductType.INAPP).build());
        QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder().
                setProductList(productList).build();
        billingClient.queryProductDetailsAsync(queryProductDetailsParams, new ProductDetailsResponseListener() {
            public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> list) {
                for (ProductDetails e: list) {
                }
            }
        });
    }

    public void buy(String productId) {
        Log.d(TAG, "buy: " + productId);
        if(!billingClient.isReady()){
            Toast.makeText(context,"BillingClient is not ready", Toast.LENGTH_SHORT).show();
        }
        List<QueryProductDetailsParams.Product> productList= new ArrayList<>();
        productList.add(QueryProductDetailsParams.Product.newBuilder()
                .setProductId(productId).setProductType(BillingClient.ProductType.INAPP).build());
        QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder().
                setProductList(productList).build();
        billingClient.queryProductDetailsAsync(queryProductDetailsParams, new ProductDetailsResponseListener() {
            public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> list) {
                Log.d(TAG, billingResult.toString());
                Log.d(TAG, billingResult.getResponseCode()+"");
                Log.d(TAG, billingResult.getDebugMessage());
                if (list.size() > 0) {
                    Log.d(TAG, "buy: bbb");
                    ProductDetails details = list.get(0);
                    ImmutableList<BillingFlowParams.ProductDetailsParams> productDetailsParamsList = ImmutableList.of(
                            BillingFlowParams.ProductDetailsParams.newBuilder()
                                    // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
                                    .setProductDetails(details)
//                                    // For one-time products, "setOfferToken" method shouldn't be called.
//                                    // For subscriptions, to get an offer token, call
//                                    // ProductDetails.subscriptionOfferDetails() for a list of offers
//                                    // that are available to the user.
//                                    .setOfferToken(selectedOfferToken)
                                    .build());
                    BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                            .setProductDetailsParamsList(productDetailsParamsList)
                            .build();
                    // Launch the billing flow
                    billingResult = billingClient.launchBillingFlow(context, billingFlowParams);
                } else {
                    onPayFail(-4);
                }
            }
        });
    }
    public void resumeBuy() {
        this.queryPurchasesAsync();
    }
    private void queryPurchasesAsync() {
        if(billingClient!=null){
            if(!billingClient.isReady()){
                Toast.makeText(context,"BillingClient is not ready", Toast.LENGTH_SHORT).show();
            }
            billingClient.queryPurchasesAsync(
                    QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(),
                    new PurchasesResponseListener() {
                        public void onQueryPurchasesResponse(
                                BillingResult billingResult,
                                List<Purchase> purchases) {
                            if(billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK){
                                if(purchases!=null&&purchases.size()>0){
                                    for (Purchase purchase:purchases){
                                        onPaySuccess(purchase);
//                                        handlePurchase(purchase);
                                    }
                                }
                            }
                        }
                    }
            );
        }
    }
//    private void handlePurchase(final Purchase purchase) {
//        ConsumeParams consumeParams =
//                ConsumeParams.newBuilder()
//                        .setPurchaseToken(purchase.getPurchaseToken())
//                        .build();
//        ConsumeResponseListener listener = new ConsumeResponseListener() {
//            @Override
//            public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
//                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
//                    Log.e(TAG, "getPurchaseToken: "+ purchase.getPurchaseToken() );
//                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
//                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
//                }
//            }
//        };
//        if(billingClient != null){
//            billingClient.consumeAsync(consumeParams, listener);
//        }
//    }
    public void consumePay(String token) {
        ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(token).build();
        billingClient.consumeAsync(consumeParams, new ConsumeResponseListener() {
            @Override
            public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
                String str = billingResult.getResponseCode() == BillingResponseCode.OK?"success":"fail";
                Log.d(TAG, "consumeAsync "+str);
            }
        });
    }
}
